package cn.ayanami.blog.system.bean;

import java.io.Serial;
import java.io.Serializable;
import java.util.List;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.swagger.v3.oas.annotations.Parameter;
import org.springframework.validation.ObjectError;

import cn.ayanami.blog.system.constant.CommonConstant;


/**
 * 接口返回对象
 * @param <T>
 */
public class Result<T> implements Serializable {

	@Serial
	private static final long serialVersionUID = 1L;
	private static final ObjectMapper mapper = new ObjectMapper();

	/**
	 * 成功标志
	 */
	@Parameter(name = "成功标志")
	private boolean success = true;

	/**
	 * 返回处理消息
	 */
	@Parameter(name = "返回处理消息")
	private String message = "操作成功！";

	/**
	 * 返回代码
	 */
	@Parameter(name = "返回代码")
	private Integer code = 0;
	
	/**
	 * 返回数据对象 data
	 */
	@Parameter(name = "返回数据对象")
	private T data;
	
	/**
	 * 时间戳
	 */
	@Parameter(name = "时间戳")
	private long timestamp = System.currentTimeMillis();

	public Result() {
		
	}
	
	public Result<T> success(String message) {
		this.message = message;
		this.code = CommonConstant.REQUEST_CODE.SUCCESS.getValue();
		this.success = true;
		return this;
	}

	@Deprecated
	public static Result<Object> ok() {
		Result<Object> r = new Result<>();
		r.setSuccess(true);
		r.setCode(CommonConstant.REQUEST_CODE.SUCCESS.getValue());
		r.setMessage("成功");
		return r;
	}

	@Deprecated
	public static Result<Object> ok(String msg) {
		Result<Object> r = new Result<>();
		r.setSuccess(true);
		r.setCode(CommonConstant.SC_OK_200);
		r.setMessage(msg);
		return r;
	}

	@Deprecated
	public static Result<Object> ok(Object data) {
		Result<Object> r = new Result<>();
		r.setSuccess(true);
		r.setCode(CommonConstant.SC_OK_200);
		r.setData(data);
		return r;
	}

	public static<T> Result<T> OK() {
		Result<T> r = new Result<>();
		r.setSuccess(true);
		r.setCode(CommonConstant.SC_OK_200);
		r.setMessage("成功");
		return r;
	}

	public static<T> Result<T> OK(T data) {
		Result<T> r = new Result<>();
		r.setSuccess(true);
		r.setCode(CommonConstant.SC_OK_200);
		r.setData(data);
		return r;
	}

	public static<T> Result<T> OK(String msg, T data) {
		Result<T> r = new Result<>();
		r.setSuccess(true);
		r.setCode(CommonConstant.SC_OK_200);
		r.setMessage(msg);
		r.setData(data);
		return r;
	}

	public static<T> Result<T> error(String msg, T data) {
		Result<T> r = new Result<>();
		r.setSuccess(false);
		r.setCode(CommonConstant.REQUEST_CODE.INTERNAL_ERROR.getValue());
		r.setMessage(msg);
		r.setData(data);
		return r;
	}

	public static <T>Result<T> error(String msg) {
		return error(CommonConstant.REQUEST_CODE.INTERNAL_ERROR.getValue(), msg);
	}
	
	public static <T>Result<T> error(int code, String msg) {
		Result<T> r = new Result<>();
		r.setCode(code);
		r.setMessage(msg);
		r.setSuccess(false);
		return r;
	}

	public static Result<String> validateError(List<ObjectError> errors){
		Result<String> r = new Result<>();
		String s="unknown error";
		try {
			s = mapper.writeValueAsString(errors);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		r.setData(s);
		r.setCode(111);
		r.setMessage("validate error");
		r.setSuccess(false);
		return r;

	}

	public Result<T> systemError(String message) {
		this.message = message;
		this.code = CommonConstant.REQUEST_CODE.INTERNAL_ERROR.getValue();
		this.success = false;
		return this;
	}
	/**
	 * 无权限访问返回结果
	 */
	public static Result<Object> noauth(String msg) {
		return error(CommonConstant.REQUEST_CODE.NO_AUTH.getValue(), msg);
	}



    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }



    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }
    
}

